﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using Negocio.catalogos;
using Negocio.clases_tontas;
using System.Text;

namespace Presentacion
{
    public partial class Horario : System.Web.UI.Page
    { 
        protected void Page_Load(object sender, EventArgs e)
        {
            if (Request.QueryString["ca"] != null )
            {
                //Lista de clase de css para los eventos
                var color = new List<string> { "external-event bg-red", "external-event bg-yellow", "external-event bg-aqua", "external-event bg-blue", "external-event bg-light-blue", "external-event bg-green", "external-event bg-navy", "external-event bg-teal", "external-event bg-lime", "external-event bg-light-orange", "external-event bg-light-fuchsia", "external-event bg-light-purple", "external-event bg-light-maroon" };
                int index = 0;
                //Verificacion de la primera visita a la pagina
                if (!IsPostBack)
                {
                    if (Session["idDocente"] != null || Session["admin"] != null)
                    {
                        try
                        {
                            string id = Session["idDocente"].ToString();
                            StringBuilder codigoHTML = new StringBuilder();
                               codigoHTML.Append( "<div id='external-events'>");
                            List<string> Distribucion = new List<string>();
                            //Consulta de distribuciones por idDocente
                            catalogoDistribucion _objServicioDocente = new catalogoDistribucion();
                            var codigoCarreraDescriptado = new Presentacion.encriptaje().decodeControlAsistencia(Request.QueryString["ca"].ToString());
                            int codigoCarrera = int.Parse(codigoCarreraDescriptado);
                            var resulCarrera = new catalogoCarrera().obtenerCarreraxID(codigoCarrera).First();

                            Label1.Text = "CARRERA DE "+ resulCarrera.carrera;
                            var resultDistribucion = _objServicioDocente.obtenerDistribucion(Convert.ToInt32(id)).Where(C => C.idCarrera == codigoCarrera);
                            if (resultDistribucion.Count() > 0)
                            {
                                foreach (var item in resultDistribucion)
                                {
                                    index++;
                                    codigoHTML.Append(" <div class='" + color[index] + "'>" + item.Nombre.ToString() + "</div>");
                                } //cierre foreach eventos
                                codigoHTML.Append(" </div>");
                                eventos.InnerHtml = codigoHTML.ToString();
                                
                            }
                            else
                            {
                                codigoHTML.Append( "Intente loguearse nuevo.</div>");
                                eventos.InnerHtml = codigoHTML.ToString();
                            }//Cierre condicion
                        } //try
                        catch (Exception)
                        {

                            throw;
                        } //Cierre cathc
                    }
                    else
                    {
                        Server.Transfer("Default.aspx");
                    }
                    //cierre verificacion sesion 

                } // Cierra postBack 
            }
            else
            {
                Response.Redirect("carreras.aspx");
            }
        } //Cierre evento Load
        
        /// <summary>
        /// Modificar horario de clases
        /// </summary>
        /// <param name="cevent">Objeto de la clase horarioClases como parametro del metodo</param>
        /// <returns>Cadena de caracteres mostrando un mensaje de confirmacion o error</returns>
        [System.Web.Services.WebMethod(true)]
        public static string UpdateEvent(horarioClases cevent)
        {
            try
            {
                int idSesion = int.Parse(cevent.detalle); //Desde la pagina envio el codigo del docente para hacer la consulta

                //Creacion de objetos
                catalogoHorario _objCatalogoHorario = new catalogoHorario();
                horarioClases _objHorario = new horarioClases();

                //Objeto de validacion de horas clases
                catalogoDistribucion _objDistribucion = new catalogoDistribucion();
                List<distribucion> _objDistribucionHoras = new List<distribucion>();

                var codigoCarreraDescriptado = new Presentacion.encriptaje().decodeControlAsistencia(cevent.backGroundColor);
                int codigoCarrera = int.Parse(codigoCarreraDescriptado);

                var listaDistribucion = _objDistribucion.obtenerDistribucion(idSesion).Where(C => C.Nombre == cevent.nombre && C.idCarrera == codigoCarrera).First();//Consulta de distribucion para obtener el id mediante nombre de la distribucion 
                _objDistribucionHoras.Add(new distribucion(listaDistribucion.idDistribucion, listaDistribucion.Nombre, 0, 0));//Carga de districion para acumular el nro de horas

                DateTime horaInicio = Convert.ToDateTime(cevent.horaEntrada);//Obtiene fecha actual
                DateTime horaFin = Convert.ToDateTime(cevent.horaSalida);//Obtiene fecha actual

                TimeSpan nroHoraDistribucionTIme = horaFin -horaInicio;


                // Difference in days.
                int differenceInDays = nroHoraDistribucionTIme.Minutes;

                if ((differenceInDays % 60) == 0)
                {

                    //Nro de horas actuales
                    int restaDiaActual = (horaFin.Subtract(horaInicio)).Hours;
                    int nroHoraDistribucion = default(int);

                    //Obtiene la suma de la base de datos
                    foreach (var item in _objCatalogoHorario.obtenerHorarioXidPeriodoANDidDistribucion(int.Parse(cevent.idPeriodo.ToString()), listaDistribucion.idDistribucion))
                    {
                        DateTime dia = DateTime.Now; //Obtiene dia actual

                        TimeSpan _intervaloHoraEntrada = TimeSpan.Parse(item.horaEntrada);
                        TimeSpan _intervaloHoraSalida = TimeSpan.Parse(item.horaSalida);

                        DateTime dia1 = new DateTime(dia.Year, dia.Month, dia.Day, _intervaloHoraEntrada.Hours, _intervaloHoraEntrada.Minutes, 0); //Hora Inicio 
                        DateTime dia2 = new DateTime(dia.Year, dia.Month, dia.Day, _intervaloHoraSalida.Hours, _intervaloHoraSalida.Minutes, 0);  //hora Fin
                        nroHoraDistribucion = (dia2.Subtract(dia1)).Hours;

                        //if (item.idDetalleHorario == cevent.idDetalleHorario)
                        //{
                        //    if (restaDiaActual < nroHoraDistribucion)
                        //    {
                        //        nroHoraDistribucion = nroHoraDistribucion - (nroHoraDistribucion - restaDiaActual);
                        //    }
                        //}

                        _objDistribucionHoras[0].horas = _objDistribucionHoras[0].horas + nroHoraDistribucion;

                    }

                    var consultaEventoActual = _objCatalogoHorario.obtenerHorarioxID(int.Parse(cevent.idDetalleHorario.ToString())).FirstOrDefault();

                    if (consultaEventoActual != null)
                    {

                        TimeSpan _intervaloHoraEntrada = TimeSpan.Parse(consultaEventoActual.horaEntrada);
                        TimeSpan _intervaloHoraSalida = TimeSpan.Parse(consultaEventoActual.horaSalida);

                        DateTime _dia = DateTime.Now; //Obtiene dia actual
                        DateTime _dia1 = new DateTime(_dia.Year, _dia.Month, _dia.Day, _intervaloHoraEntrada.Hours, _intervaloHoraEntrada.Minutes, 0); //Hora Inicio 
                        DateTime _dia2 = new DateTime(_dia.Year, _dia.Month, _dia.Day, _intervaloHoraSalida.Hours, _intervaloHoraSalida.Minutes, 0);  //hora Fin
                        nroHoraDistribucion = (_dia2.Subtract(_dia1)).Hours;
                    }
                    else
                    {
                        nroHoraDistribucion = 0;
                    }


                    int restaDelosEventoBaPa = restaDiaActual - nroHoraDistribucion;

                    int? sumaDeHorasPantalla = _objDistribucionHoras[0].horas + restaDelosEventoBaPa;
                    if (sumaDeHorasPantalla <= listaDistribucion.horas)
                    {
                        DateTime _dia = DateTime.Now; //Obtiene dia actual
                        _objHorario.idDetalleHorario = Convert.ToInt32(cevent.idDetalleHorario);
                        _objHorario.detalle = horaInicio.DayOfWeek.ToString();
                        _objHorario.horaEntrada = horaInicio.Hour.ToString() + ":" + horaInicio.Minute.ToString();
                        _objHorario.horaSalida = horaFin.Hour.ToString() + ":" + horaFin.Minute.ToString();
                        _objHorario.ultimoAcceso = _dia;
                        if (_objCatalogoHorario.modificarHorario(_objHorario))
                        {
                            return "Hora modificado";
                        }
                        else
                        {
                            return "Error al procesar Hora";
                        }

                    }
                    else
                    {
                        return "false";
                    }
                }
                else
                {
                    return "Por favor solo ingrese intervalos de una hora.";
                }
            } //Cierre try
            catch (Exception)
            {
                return "Error al modificar Hora";
            } //Cierre catch
        } //Cierre Metodo actualizar horario

        /// <summary>
        /// Modificar horario de clases cuando se arrastra los eventos
        /// </summary>
        /// <param name="cvent">Objeto de la clase horarioClases como parametro del metodo</param>
        /// <returns>Cadena de caracteres mostrando un mensaje de confirmacion o error</returns>
        [System.Web.Services.WebMethod(true)]
        public static string UpdateEventDrop(horarioClases cvent)
        {
            try
            {
                catalogoHorario _objCatalogoHorario = new catalogoHorario();
                horarioClases _objHorario = new horarioClases();
                List<distribucion> _objDistribucionHoras = new List<distribucion>();

                DateTime horaInicio = Convert.ToDateTime(cvent.horaEntrada);//Obtiene fecha actual
                DateTime horaFin = Convert.ToDateTime(cvent.horaSalida);//Obtiene fecha actual

                int restaDiaActual = (horaFin.Subtract(horaInicio)).Hours;

                TimeSpan nroHoraDistribucion = horaFin -horaInicio;
                int nroHoraDistribucionTotal = 0;

                // Difference in days.
                int differenceInDays = nroHoraDistribucion.Minutes;

                if ((differenceInDays % 60) == 0)
                {
                    var resulthorarioID = new catalogoHorario().obtenerHorarioxID(Convert.ToInt32(cvent.idDetalleHorario)).FirstOrDefault();

                    if (resulthorarioID != null)
                    {
                        _objDistribucionHoras.Add(new distribucion(resulthorarioID.idDistribucion.idDistribucion, resulthorarioID.idDistribucion.Nombre, 0, 0));//Carga de districion para acumular el nro de horas
                        TimeSpan _intervaloHoraEntrada = TimeSpan.Parse(resulthorarioID.horaEntrada);
                        TimeSpan _intervaloHoraSalida = TimeSpan.Parse(resulthorarioID.horaSalida);

                        //Obtiene la suma de la base de datos
                        foreach (var item in _objCatalogoHorario.obtenerHorarioXidPeriodoANDidDistribucion((int)resulthorarioID.idPeriodo, resulthorarioID.idDistribucion.idDistribucion))
                        {
                            DateTime dia = DateTime.Now; //Obtiene dia actual

                            _intervaloHoraEntrada = TimeSpan.Parse(item.horaEntrada);
                            _intervaloHoraSalida = TimeSpan.Parse(item.horaSalida);

                            DateTime dia1 = new DateTime(dia.Year, dia.Month, dia.Day, _intervaloHoraEntrada.Hours, _intervaloHoraEntrada.Minutes, 0); //Hora Inicio 
                            DateTime dia2 = new DateTime(dia.Year, dia.Month, dia.Day, _intervaloHoraSalida.Hours, _intervaloHoraSalida.Minutes, 0);  //hora Fin
                            nroHoraDistribucionTotal = (dia2.Subtract(dia1)).Hours;

                            _objDistribucionHoras[0].horas = _objDistribucionHoras[0].horas + nroHoraDistribucionTotal;

                        }

                        _intervaloHoraEntrada = TimeSpan.Parse(resulthorarioID.horaEntrada);
                        _intervaloHoraSalida = TimeSpan.Parse(resulthorarioID.horaSalida);

                        DateTime _dia = DateTime.Now; //Obtiene dia actual
                        DateTime _dia1 = new DateTime(_dia.Year, _dia.Month, _dia.Day, _intervaloHoraEntrada.Hours, _intervaloHoraEntrada.Minutes, 0); //Hora Inicio 
                        DateTime _dia2 = new DateTime(_dia.Year, _dia.Month, _dia.Day, _intervaloHoraSalida.Hours, _intervaloHoraSalida.Minutes, 0);  //hora Fin
                        nroHoraDistribucionTotal = (_dia2.Subtract(_dia1)).Hours;


                        int restaDelosEventoBaPa = restaDiaActual - nroHoraDistribucionTotal;

                        int? sumaDeHorasPantalla = _objDistribucionHoras[0].horas + restaDelosEventoBaPa;
                        if (sumaDeHorasPantalla <= resulthorarioID.idDistribucion.horas)
                        {
                           
                            _objHorario.idDetalleHorario = Convert.ToInt32(cvent.idDetalleHorario);
                            _objHorario.detalle = horaInicio.DayOfWeek.ToString();
                            _objHorario.horaEntrada = horaInicio.Hour.ToString() + ":" + horaInicio.Minute.ToString();
                            _objHorario.horaSalida = horaFin.Hour.ToString() + ":" + horaFin.Minute.ToString();
                            _objHorario.ultimoAcceso = _dia;
                            if (_objCatalogoHorario.modificarHorario(_objHorario))
                            {
                                return "Hora modificado";
                            }
                            else
                            {
                                return "Error al procesar Hora";
                            }
                        }
                        else
                        {
                            return "false";
                        }
                    
                    }
                    else
                    {
                        return "Error al modificar, recargue página.";
                    }

                    
                }
                else
                {
                    return "Solo se permite modificar por intervalos de una hora.";
                }
            }
            catch (Exception)
            {

                return "Error al procesar Hora";
            }
 
        }
        /// <summary>
        /// Metodo para añadir distribucion al horario
        /// </summary>
        /// <param name="cEvent">Objeto de la clase horarioClases como parametro del metodo</param>
        /// <returns>Cadena de caracteres mostrando un mensaje de confirmacion o error</returns>
        [System.Web.Services.WebMethod(true)]
        public static string addEventHora(horarioClases cEvent)
        {
            try
            {
                int idSesion = cEvent.idDetalleHorario; //Desde la pagina envio el codigo del docente para hacer la consulta

                //Creacion de objetos catalogos
                catalogoHorario _objCatalogoHorario = new catalogoHorario();
                catalogoDistribucion _objDistribucion = new catalogoDistribucion();

                //Creacion de los objetos clases para ser llenados 
                horarioClases _objCalendarioHorario = new horarioClases();
                List<distribucion> _objDistribucionHoras = new List<distribucion>();
                var codigoCarreraDescriptado = new Presentacion.encriptaje().decodeControlAsistencia(cEvent.detalle);
                int codigoCarrera = int.Parse(codigoCarreraDescriptado);

                var listaDistribucion = _objDistribucion.obtenerDistribucion(idSesion).Where(C => C.Nombre == cEvent.nombre && C.idCarrera == codigoCarrera).First();//Consulta de distribucion para obtener el id mediante nombre de la distribucion 

                _objDistribucionHoras.Add(new distribucion(listaDistribucion.idDistribucion, listaDistribucion.Nombre, 0,0));//Carga de districion para acumular el nro de horas
                             
                foreach (var item in _objCatalogoHorario.obtenerHorarioXidPeriodoANDidDistribucion(int.Parse(cEvent.idPeriodo.ToString()), listaDistribucion.idDistribucion))
                {
                    DateTime dia = DateTime.Now; //Obtiene dia actual

                    //if (dia.DayOfWeek.ToString()!=item.detalle)
                    //{

                    TimeSpan _intervaloHoraEntrada = TimeSpan.Parse(item.horaEntrada);
                    TimeSpan _intervaloHoraSalida = TimeSpan.Parse(item.horaSalida);
                    DateTime dia1 = new DateTime(dia.Year, dia.Month, dia.Day, _intervaloHoraEntrada.Hours, _intervaloHoraEntrada.Minutes, 0);  //Hora Inicio 
                    DateTime dia2 = new DateTime(dia.Year, dia.Month, dia.Day, _intervaloHoraSalida.Hours, _intervaloHoraSalida.Minutes, 0);  //hora Fin
                        int nroHoraDistribucion = (dia2.Subtract(dia1)).Hours;

                        _objDistribucionHoras[0].horas = _objDistribucionHoras[0].horas + nroHoraDistribucion; 
                    //}
                    //else
                    //{
                    //    return "false2";
                    //}                   

                }

                //Resta para verificar para permitir agregar evento si al docente le falta 
                //agregar un hora de clases

                int? resta = listaDistribucion.horas - _objDistribucionHoras[0].horas;

                //Condicion para verificar si alcanzo nro horas maximo o la resta 
                if ((_objDistribucionHoras[0].horas < listaDistribucion.horas) || (resta == 1))
                {
                    DateTime dia = DateTime.Now; //Obtiene dia actual
                    DateTime horaInicio = Convert.ToDateTime(cEvent.horaEntrada);//Obtiene fecha actual
                    DateTime horaFin = horaInicio.AddHours(1);
                    _objCalendarioHorario.idDistribucion = listaDistribucion;
                    _objCalendarioHorario.idPeriodo = cEvent.idPeriodo;
                    _objCalendarioHorario.detalle = horaInicio.DayOfWeek.ToString();
                    _objCalendarioHorario.horaEntrada = horaInicio.Hour.ToString() + ":" + horaInicio.Minute.ToString();
                    _objCalendarioHorario.horaSalida = horaFin.Hour.ToString() + ":" + horaFin.Minute.ToString();
                    _objCalendarioHorario.backGroundColor = cEvent.backGroundColor;
                    _objCalendarioHorario.borderColor = cEvent.borderColor;
                    _objCalendarioHorario.ultimoAcceso = dia;
                    if (_objCatalogoHorario.agregarHorario(_objCalendarioHorario))
                    {
                        return "Hora agregado";
                    }
                    else
                    {
                        return "Error al procesar Hora";
                    }
                }
                else
                {
                    return "false";
                }
                
                
            } //Cierre try
            catch (Exception)
            {
                throw;
            }//Cierre catch

        }//Cierre metodo addEvent 

        /// <summary>
        /// Metodo para obtener el horario de clases filtrado por docente y el periodo actual
        /// </summary>
        /// <param name="_idDocente">Número identificador al docente actual para filtrar la distribucion por docente</param>
        /// <param name="_idPeriodo">Número identificador de periodo actual para filtrar el horario</param>
        /// <returns>Array de los eventos del horario de clase</returns>
        [System.Web.Services.WebMethod(true)]
        public static string obtenerHorario(int _idDocente, int _idPeriodo, string _codCarrera)
        {
            catalogoHorario _objCatalagoHorario = new catalogoHorario();
            horarioClases _objHorarioClases = new horarioClases();

            
            string eventos = "["; 

            catalogoDistribucion _objDistribucion = new catalogoDistribucion();
            int _idCarrera = int.Parse(new Presentacion.encriptaje().decodeControlAsistencia(_codCarrera));
            var listaDistribucion = _objDistribucion.obtenerDistribucion(_idDocente).Where(C => C.idCarrera == _idCarrera).ToList();
            //Inicio de bucle de nro de distribucion del docente
            int nroLista = 0;
            List<distribucion> _horaDistribucion = new List<distribucion>();
            
            for (int i = 0; i < listaDistribucion.Count(); i++)
            {
                int contador = 0;   
                //Carga de eventos
                foreach (var item in _objCatalagoHorario.obtenerHorarioXidPeriodoANDidDistribucion(_idPeriodo, listaDistribucion[nroLista].idDistribucion))
                {
                    contador += 1;
                    DateTime dia = DateTime.Now; //Obtiene dia actual
                  
                    //Buscar inicio de semana
                    //Inicio busqueda inicio de semana
                    while (dia.DayOfWeek != DayOfWeek.Monday)
                    {
                        if (dia.DayOfWeek == DayOfWeek.Sunday)
                        {
                            dia = dia.AddDays(1);
                        }
                        else
                        {
                            dia = dia.AddDays(-1);
                        }                        
                    }

                    while (dia.DayOfWeek.ToString() != item.detalle)
                    {
                        dia = dia.AddDays(1);
                    }//fin busqueda dia de la semana 

                    //Conversion Tiempo
                    TimeSpan _intervaloHoraEntrada = TimeSpan.Parse(item.horaEntrada);
                    TimeSpan _intervaloHoraSalida = TimeSpan.Parse(item.horaSalida);
                    
                    eventos = string.Concat(eventos, "{" +
                      "id: '" + item.idDetalleHorario + "'," +
                      "title: '" + HttpContext.Current.Server.HtmlEncode(item.idDistribucion.Nombre) + "'," +                      
                      "start: new Date(" + dia.Year + "," + dia.Month + "-1," + dia.Day + "," + _intervaloHoraEntrada.Hours + ","+_intervaloHoraEntrada.Minutes+")," +
                      "end: new Date(" + dia.Year + "," + dia.Month + "-1," + dia.Day + "," + _intervaloHoraSalida.Hours + "," + _intervaloHoraSalida.Minutes + ")," +
                      "allDay: false," +
                      "backgroundColor: '" + item.backGroundColor +
                      "',borderColor: '" + item.borderColor +
                      "'},");
                    if (contador==1)
                    {
                        
                    }
                    
                } //Fin bucle eventos distribucion
                nroLista++;
            }//Fin bucle de lista distribucion
            DateTime dia2 = DateTime.Now; //Obtiene dia actual
            for (int i = 1; i <= 31; i++)
            {
                eventos = string.Concat(eventos, "{" +
                                 "id: 'CASYS'," +
                                 "title: ' --- CASYS --- '," +
                                 "start: new Date(" + dia2.Year + "," + dia2.Month + "-1,"+ i +",7,0)," +
                                 "end: new Date(" + dia2.Year + "," + dia2.Month + "-1," + i + ",7,30)," +
                                 "allDay: false," +
                                 "backgroundColor: '#000000'," +
                                 "borderColor: '#000000'},");

                eventos = string.Concat(eventos, "{" +
                                     "id: 'CASYS'," +
                                     "title: 'CASYS RECESO'," +
                                     "start: new Date(" + dia2.Year + "," + dia2.Month + "-1," + i + ",9,30)," +
                                     "end: new Date(" + dia2.Year + "," + dia2.Month + "-1," + i + ",10,00)," +
                                     "allDay: false," +
                                     "backgroundColor: '#000000'," +
                                     "borderColor: '#000000'},");
                eventos = string.Concat(eventos, "{" +
                                 "id: 'CASYS'," +
                                 "title: 'CASYS RECESO'," +
                                 "start: new Date(" + dia2.Year + "," + dia2.Month + "-1," + i + ",20,0)," +
                                 "end: new Date(" + dia2.Year + "," + dia2.Month + "-1," + i + ",20,15)," +
                                 "allDay: false," +
                                 "backgroundColor: '#000000'," +
                                 "borderColor: '#000000'},"); 
            }
            
            
            eventos = string.Concat(eventos, "]");
            return eventos;
            
        }
    }
}